#pragma once

#include "Den_TFuncTraits.h"
#include "Den_Arg.h"

#define Gen_check_number_of_args(num) \
    {\
        const bool most_be_empty = num>eNum_args;  const bool arg_is_empty = Array[num-1].IsEmpty();\
        const bool ERROR_TOO_MANY_ARG_##num = most_be_empty == !arg_is_empty;\
        if(needAlarm  && ERROR_TOO_MANY_ARG_##num ) assert(!ERROR_TOO_MANY_ARG_##num);\
        if(!needAlarm && ERROR_TOO_MANY_ARG_##num ) return false;\
    }

#define Gen_check_type(num) \
    const bool ERROR_TYPE_ARG##num = Array[num-1].CheckType<Arg##num>()==false;\
    if(needAlarm  && ERROR_TYPE_ARG##num) assert(!ERROR_TYPE_ARG##num);\
    if(!needAlarm && ERROR_TYPE_ARG##num) return false;

#define Gen_check_qualifier(num) \
    const bool ERROR_QUALIFIER_ARG##num = Array[num-1].CheckQualifer<Arg##num>()==false; \
    if(needAlarm  && ERROR_QUALIFIER_ARG##num) assert(!ERROR_QUALIFIER_ARG##num);\
    if(!needAlarm && ERROR_QUALIFIER_ARG##num) return false;\
    if(num>eNum_args) { FOR_TESTING(std::cout<<"CHECKING...............SUCCESS\n\n"); return true; }

#define Gen_check_argument(num) Gen_check_number_of_args(num) Gen_check_type(num) Gen_check_qualifier(num)

namespace Den{

template<class tFunc> bool TCheck_func_args( Arg (&Array)[7], const bool needAlarm=false)
{
    enum { eNum_args = TFuncTraits<tFunc>::eNUM_OF_ARG };
    typedef typename TFuncTraits<tFunc>::Arg_t::Arg1 Arg1; typedef typename TFuncTraits<tFunc>::Arg_t::Arg2 Arg2;
    typedef typename TFuncTraits<tFunc>::Arg_t::Arg3 Arg3; typedef typename TFuncTraits<tFunc>::Arg_t::Arg4 Arg4;
    typedef typename TFuncTraits<tFunc>::Arg_t::Arg5 Arg5; typedef typename TFuncTraits<tFunc>::Arg_t::Arg6 Arg6;
    typedef typename TFuncTraits<tFunc>::Arg_t::Arg7 Arg7;

    FOR_TESTING(std::cout<<"CHECK ARG1\n"); Gen_check_argument(1);
    FOR_TESTING(std::cout<<"CHECK ARG2\n"); Gen_check_argument(2);
    FOR_TESTING(std::cout<<"CHECK ARG3\n"); Gen_check_argument(3);
    FOR_TESTING(std::cout<<"CHECK ARG4\n"); Gen_check_argument(4);
    FOR_TESTING(std::cout<<"CHECK ARG5\n"); Gen_check_argument(5);
    FOR_TESTING(std::cout<<"CHECK ARG6\n"); Gen_check_argument(6);
    FOR_TESTING(std::cout<<"CHECK ARG7\n"); Gen_check_argument(7);
    return true;
}

#undef Gen_check_argument
#undef Gen_check_type 
#undef Gen_check_qualifier

}//namespace Den
